package org.fast.develop.logicflow.ws.thread;

import lombok.extern.slf4j.Slf4j;
import org.fast.develop.logicflow.LogicFlowManagementConfiguration;
import org.fast.develop.logicflow.runtime.cache.ThreadLog;
import org.fast.develop.logicflow.runtime.debug.ExecuteDebugConfig;
import org.fast.develop.logicflow.ws.message.RunTimeMessage;
import org.fast.develop.logicflow.ws.message.StartMessage;
import org.fast.develop.logicflow.ws.task.LogicFlowDebugTask;

import java.util.Date;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author czh
 * @version V1.0
 * @data Created on 2023-01-12 14:43
 */
@Slf4j
public class ThreadExecuteManager {

    private ThreadStore threadStore;

    private ExecutorService executorService;

    private LogicFlowManagementConfiguration logicFlowManagementConfiguration;

    public ThreadExecuteManager(ThreadStore threadStore, LogicFlowManagementConfiguration logicFlowManagementConfiguration) {
        this.executorService = Executors.newFixedThreadPool(3);
        this.threadStore = threadStore;
        this.logicFlowManagementConfiguration = logicFlowManagementConfiguration;
    }

    public void start(String sessionId, StartMessage startMessage) {
        ExecuteDebugConfig debugConfig = ExecuteDebugConfig.OfDebug()
                .setStepOverFlag(false)
                .setSessionId(sessionId)
                .setType(startMessage.getType())
                .setDebugResourceIds(startMessage.getDebugResourceIds());
        Thread thread = new Thread(() -> new LogicFlowDebugTask(logicFlowManagementConfiguration)
                .run(sessionId, startMessage));
        threadStore.put(sessionId, new ThreadLog(new Date(), thread, debugConfig));
        executorService.execute(thread);
    }

    public void run(String sessionId, RunTimeMessage messageObj) {
        ThreadLog threadLog = threadStore.get(sessionId);
        if (Objects.nonNull(threadLog)) {
            Thread thread = threadLog.getThread();
            ExecuteDebugConfig executeDebugConfig = ExecuteDebugConfig.OfDebug()
                    .setSessionId(sessionId)
                    .setType(messageObj.getType())
                    .setDebugResourceIds(messageObj.getDebugResourceIds());
            if (Objects.nonNull(messageObj.getIsOpen())) {
                executeDebugConfig.setIsOpen(messageObj.getIsOpen());
            }
            threadLog.setExecuteDebugConfig(executeDebugConfig);
            threadStore.put(sessionId, threadLog);
            synchronized (thread) {
                thread.notify();
            }
        } else {
            log.warn("sessionId = {} 获取ThreadLog不存在", sessionId);
        }

    }

    public void end(String sessionId) {
        ThreadLog threadLog = threadStore.get(sessionId);
        if (Objects.nonNull(threadLog)) {
            Thread thread = threadLog.getThread();
            thread.stop();
            threadStore.remove(sessionId);
        }
    }
}
